package com.chat.business.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chat.business.common.thread_local.UserIdThreadLocal;
import com.chat.business.mapper.UserMapper;
import com.chat.business.service.IUserService;
import com.chat.business.utils.RedisHashUtil;
import com.chat.common.common.constant.RedisKeyConstant;
import com.chat.common.entity.User;
import com.chat.common.enums.NoticeType;
import com.chat.common.utils.DtoVoUtil;
import com.chat.common.vo.NoticeVO;
import com.chat.common.vo.R;
import com.chat.common.vo.UserVo;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author weikjie
 * @since 2024-03-29
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private RedisHashUtil redisHashUtil;

    /**
     * 根据关键词（账号或者用户名）查询用户，
     * @param keyword
     * @return
     */
    @Override
    public List<User> findByKeyword(String keyword) {
        LambdaQueryWrapper<User> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(User::getAccount,keyword)
                .or()
                .like(User::getUsername,keyword);
        return list(lambdaQueryWrapper);
    }

    /**
     * 更新用户信息
     * @param userVo
     * @return
     */
    @Override
    public R<UserVo> updateInfo(UserVo userVo) {
        User user=new User();
        BeanUtil.copyProperties(userVo,user);
        Long userId= UserIdThreadLocal.get();
        user.setId(userId);
        updateById(user);
        return R.succeed(userVo);
    }

    /**
     * 下线
     * @param ID
     * @return
     */
    @Override
    public R offline(String ID) {
        User user = getById(ID);
        if(user==null) return R.failed("用户id错误");
        String token = (String) redisTemplate.opsForValue().get(RedisKeyConstant.USER_ACCOUNT_ForToken + user.getAccount());
        if(token != null && !token.isEmpty()){
            Map<String, Object> noticeData = new HashMap<>();
            UserVo userVO = DtoVoUtil.entityToDtoOrVo(user,UserVo.class);
            noticeData.put("userVO",userVO);
            //构建通知
            NoticeVO noticeVO = NoticeVO.builder().noticeType(NoticeType.compelUserOffline)
                    .publishId(Long.valueOf(ID))
                    .consumerId(Long.valueOf(ID))
                    .data(noticeData)
                    .build();
            //发布通知
            redisHashUtil.publishNotice(noticeVO);
            //清除信息
            redisTemplate.delete(RedisKeyConstant.TOKEN_USER + token);
            redisTemplate.delete(RedisKeyConstant.TOKEN_ACCOUNT + token);
            redisTemplate.delete(RedisKeyConstant.USER_ACCOUNT_ForToken + user.getAccount());
            // 检查用户是否已经在线
            Boolean isOnline = redisTemplate.opsForSet().isMember(RedisKeyConstant.ONLINE_USERS_SET_KEY, user.getAccount());
            if (isOnline != null && isOnline) {
                // 如果用户不在线，发布 "Login:user:online" 消息
                log.info("发布 Login:user:offline 消息");
                redisTemplate.convertAndSend(RedisKeyConstant.LOGIN_EXIT_USER, user.getAccount());
            }
            return R.succeed("成功退出登录");
        } else {
            return R.failed("当前用户未登录");
        }
    }
}
